{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "86b63629",
   "metadata": {},
   "source": [
    "## Streaming Real Time Options Data with ThetaData"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "56719c5d",
   "metadata": {},
   "outputs": [],
   "source": [
    "import datetime as dt\n",
    "from thetadata import (\n",
    "    Quote,\n",
    "    StreamMsg,\n",
    "    ThetaClient,\n",
    "    OptionRight,\n",
    "    StreamMsgType,\n",
    "    StreamResponseType,\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "31f14024",
   "metadata": {},
   "source": [
    "Initialize global variables for last quotes and price"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7ff7f3fa",
   "metadata": {
    "lines_to_next_cell": 1
   },
   "outputs": [],
   "source": [
    "last_call_quote = Quote()\n",
    "last_put_quote = Quote()\n",
    "price = 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "97a9b989",
   "metadata": {
    "lines_to_next_cell": 1
   },
   "outputs": [],
   "source": [
    "def callback_straddle(msg):\n",
    "    # Handle received messages\n",
    "    if msg.type != StreamMsgType.QUOTE:\n",
    "        return\n",
    "\n",
    "    global price\n",
    "\n",
    "    # Update the last call or put quote based on the message\n",
    "    if msg.contract.isCall:\n",
    "        last_call_quote.copy_from(msg.quote)\n",
    "    else:\n",
    "        last_put_quote.copy_from(msg.quote)\n",
    "\n",
    "    # Calculate straddle bid, ask, and mid prices\n",
    "    straddle_bid = round(last_call_quote.bid_price + last_put_quote.bid_price, 2)\n",
    "    straddle_ask = round(last_call_quote.ask_price + last_put_quote.ask_price, 2)\n",
    "    straddle_mid = round((straddle_bid + straddle_ask) / 2, 2)\n",
    "\n",
    "    # Get the timestamp from the message\n",
    "    time_stamp = thetadata.client.ms_to_time(msg.quote.ms_of_day)\n",
    "\n",
    "    # Print the straddle prices if they have changed\n",
    "    if price != straddle_mid:\n",
    "        print(\n",
    "            f\"time: {time_stamp} bid: {straddle_bid} mid: {straddle_mid} ask: {straddle_ask}\"\n",
    "        )\n",
    "        price = straddle_mid"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ef06d858",
   "metadata": {
    "lines_to_next_cell": 1
   },
   "outputs": [],
   "source": [
    "def stream_straddle():\n",
    "    # Initialize the ThetaClient with your credentials\n",
    "    client = ThetaClient(username=\"YOUR_EMAIL\", passwd=\"YOUR_PASSWORD\")\n",
    "    \n",
    "    # Connect to the data stream\n",
    "    client.connect_stream(callback_straddle)\n",
    "    \n",
    "    # Request quote streams for call and put options\n",
    "    req_id_call = client.req_quote_stream_opt(\n",
    "        \"SPY\", dt.date(2024, 3, 28), 475, OptionRight.CALL\n",
    "    )\n",
    "    req_id_put = client.req_quote_stream_opt(\n",
    "        \"SPY\", dt.date(2024, 3, 28), 475, OptionRight.PUT\n",
    "    )\n",
    "    \n",
    "    # Verify the subscriptions\n",
    "    if (\n",
    "        client.verify(req_id_call) != StreamResponseType.SUBSCRIBED\n",
    "        or client.verify(req_id_put) != StreamResponseType.SUBSCRIBED\n",
    "    ):\n",
    "        raise Exception(\"Unable to stream.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b91fd61c",
   "metadata": {},
   "source": [
    "Start streaming straddle quotes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "eac908f3",
   "metadata": {},
   "outputs": [],
   "source": [
    "stream_straddle()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "07210957",
   "metadata": {},
   "source": [
    "**Jason Strimpel** is the founder of <a href='https://pyquantnews.com/'>PyQuant News</a> and co-founder of <a href='https://www.tradeblotter.io/'>Trade Blotter</a>. His career in algorithmic trading spans 20+ years. He previously traded for a Chicago-based hedge fund, was a risk manager at JPMorgan, and managed production risk technology for an energy derivatives trading firm in London. In Singapore, he served as APAC CIO for an agricultural trading firm and built the data science team for a global metals trading firm. Jason holds degrees in Finance and Economics and a Master's in Quantitative Finance from the Illinois Institute of Technology. His career spans America, Europe, and Asia. He shares his expertise through the <a href='https://pyquantnews.com/subscribe-to-the-pyquant-newsletter/'>PyQuant Newsletter</a>, social media, and has taught over 1,000+ algorithmic trading with Python in his popular course **<a href='https://gettingstartedwithpythonforquantfinance.com/'>Getting Started With Python for Quant Finance</a>**. All code is for educational purposes only. Nothing provided here is financial advise. Use at your own risk."
   ]
  }
 ],
 "metadata": {
  "jupytext": {
   "cell_metadata_filter": "-all",
   "main_language": "python",
   "notebook_metadata_filter": "-all"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
